import json
from google.appengine.ext import db

services = ['Try and Buy' , 'Score board']

class Application(db.Model):
    username = db.StringProperty(required=True)
    email = db.EmailProperty(required=True)
    appName = db.StringProperty(required=True)
    appDescr = db.StringProperty(required=True)
    appService = db.StringProperty(required=True, choices=set(services))  
    appKey = db.StringProperty(required=True)
    enabled = db.BooleanProperty(required=True)
    
class TnBApplication(Application):
    tnbdurattion = db.IntegerProperty(required=True)
    tnbunit = db.StringProperty(required=True, choices=set(['days' , 'hours' , 'minutes']))
    tnbtries = db.IntegerProperty(required=True)

ranks=[u"1", u"2", u"3", u"10", u"100", u"1000", u"10000"]

class ScoreRecord(db.Model):
    score = db.StringProperty(required=True)

class TnBRecord(db.Model):
    service = db.ReferenceProperty(TnBApplication, collection_name='users')
    userdeviceid = db.StringProperty(required=True)
    durattionLeft = db.IntegerProperty(required=True)
    triesLeft = db.IntegerProperty(required=True)

    def save(self, 
             appkey):
        a_key = db.Key.from_path('TnBApplication', appkey)
        service = db.get(a_key)
        if service:
            self.service = service
            self.put()
    
    
class ScoreBoard():
    def submitScore(self, appkey, aName, aScore):
        if not self.isRegisteredForScoreBoard(appkey):
            return
        
        board = self.getDictionary(appkey)
        if board:
            board=json.loads(board)
        else:
            board = dict.fromkeys(ranks,(u"",0))
        boardList = sorted(board.items(), key=lambda x: (int(x[0])))
        swapping = ("",0)
        once = True
        for rank, (name, score) in boardList:
            if once and aScore > score:
                swapping = (name, score)
                board[rank]=(aName, aScore)
                once = False
            elif swapping[1] > 0:
                board[rank] = swapping
                swapping = (name, score)

        dbkey = db.Key.from_path('Application', appkey)
        app = db.get(dbkey)
        ScoreRecord(
                 parent = app,
                 key_name = appkey,
                 score = json.dumps(board)
                 ).put()
            
    def getScore(self, appkey):
        if not self.isRegisteredForScoreBoard(appkey):
            return
        
        board = self.getDictionary(appkey)
        if board:
            board=json.loads(board)
        else:
            board = dict.fromkeys(ranks,(u"",0))
        L = ["{'rank' : "+ rank + ", 'name' : '" + name  + "', 'score' : " + str(val) + "}" for rank, [name, val] in board.items()]
        return ('[' + ','.join(L) + ']')
    
    def isRegisteredForScoreBoard(self, appkey):
        return self.isRegistered(appkey, 'Score board')
    
    def isRegisteredForTrynBuy(self, appkey):
        return self.isRegistered(appkey, 'Try and Buy')

    # internal functions are below
    def isRegistered(self, appkey, service):
        dbkey = db.Key.from_path('Application', appkey)
        app = db.get(dbkey)
        return (app and app.appService == service)
    
    def getDictionary(self, appkey):
        dbkey = db.Key.from_path('Application', appkey)
        app = db.get(dbkey)
        for rec in ScoreRecord.all().ancestor(app):
            return rec.score
        return None
    
    def hitTryNBuy(self, appkey, userid):
        a_key = db.Key.from_path('TnBApplication', appkey)
        service = db.get(a_key)
        if service:
            # TODO: initDuration = service.tnbdurattion * service.tnbunit
            tries = service.tnbtries

            a_key = db.Key.from_path('TnBRecord', userid)
            rec = db.get(a_key)
            if rec :
                tries = rec.triesLeft - 1

            if tries < 0 :
                tries = 0
                
            TnBRecord(key_name = userid,
                      userdeviceid = userid,
                      durattionLeft = 99999,
                      triesLeft = tries).save(appkey)                
                
            return "{left :" + str(tries) + "}"
                    
        
        
    
